import { useMemo, useState, useContext, useEffect, useCallback } from "react";
import QuickBtn from "./QuickBtn";
import MorphChanger from "./MorphChanger";
import FLOWABLE from "../FLOWABLE";
import ProcessEditorContext from '../context'

const baseUrl = import.meta.env.VITE_FLOWABLE_URL

const useChangeMorph = ({
  selectedShape,
  editorManager
}) => {
  const [showMorphChanger, setShowMorphChanger] = useState(false)

  const toggleShowMorphChanger = () => {
    setShowMorphChanger((oldValue) => !oldValue)
  }

  const handleChangeMorph = (currentSelectedMorph) => {
    var stencil = undefined;
    var stencilSets = editorManager.getStencilSets().values();
    var stencilId = currentSelectedMorph.id;
    if (currentSelectedMorph.genericTaskId) {
      stencilId = currentSelectedMorph.genericTaskId;
    }
    for (var i = 0; i < stencilSets.length; i++) {
      var stencilSet = stencilSets[i];
      var nodes = stencilSet.nodes();
      for (var j = 0; j < nodes.length; j++) {
        if (nodes[j].idWithoutNs() === stencilId) {
          stencil = nodes[j];
          break;
        }
      }
    }
    if (!stencil) return;
    // Create and execute command (for undo/redo)			
    var command = new FLOWABLE.MorphToCommand(selectedShape, stencil, editorManager.getEditor());
    editorManager.executeCommands([command]);
    setShowMorphChanger(false)
  }
  return {
    showMorphChanger,
    toggleShowMorphChanger,
    handleChangeMorph
  }
}

const QuickBtns = () => {

  const [bounds, setBouds] = useState(null)

  const {
    editorManager,
    selectedShape,
    selectedShapes,
    quickMenuItems,
    morphRoles,
    getStencilItemById,
    handleQuickAction
  } = useContext(ProcessEditorContext)

  useEffect(() => {
    if (selectedShapes && selectedShapes.length === 1) {
      var selectedShape = selectedShapes.first();
      var a = editorManager.getCanvas().node.getScreenCTM();
      var absoluteXY = selectedShape.absoluteXY();

      absoluteXY.x *= a.a;
      absoluteXY.y *= a.d;
      var additionalIEZoom = 1;

      if (additionalIEZoom === 1) {
        absoluteXY.y = absoluteXY.y - jQuery("#canvasSection").offset().top + 5;
        absoluteXY.x = absoluteXY.x - jQuery("#canvasSection").offset().left;
      } else {
        var canvasOffsetLeft = jQuery("#canvasSection").offset().left;
        var canvasScrollLeft = jQuery("#canvasSection").scrollLeft();
        var canvasScrollTop = jQuery("#canvasSection").scrollTop();

        var offset = a.e - (canvasOffsetLeft * additionalIEZoom);
        var additionaloffset = 0;
        if (offset > 10) {
          additionaloffset = (offset / additionalIEZoom) - offset;
        }
        absoluteXY.y = absoluteXY.y - (jQuery("#canvasSection").offset().top * additionalIEZoom) + 5 + ((canvasScrollTop * additionalIEZoom) - canvasScrollTop);
        absoluteXY.x = absoluteXY.x - (canvasOffsetLeft * additionalIEZoom) + additionaloffset + ((canvasScrollLeft * additionalIEZoom) - canvasScrollLeft);
      }

      const bounds = new ORYX.Core.Bounds(
        a.e + absoluteXY.x,
        a.f + absoluteXY.y,
        a.e + absoluteXY.x +
        a.a * selectedShape.bounds.width(),
        a.f + absoluteXY.y +
        a.d * selectedShape.bounds.height()
      );
      setBouds(bounds)
    } else {
      setBouds(null)
    }
  }, [selectedShapes])

  const stencilItem = useMemo(() => {
    return selectedShape ? getStencilItemById(selectedShape.getStencil().idWithoutNs()) : null
  }, [selectedShape, morphRoles])

  const morphShapes = useMemo(() => {
    var _morphShapes = [];
    if (stencilItem && stencilItem.morphRole) {
      for (var i = 0; i < morphRoles.length; i++) {
        if (morphRoles[i].role === stencilItem.morphRole) {
          _morphShapes = morphRoles[i].morphOptions;
        }
      }
    }
    return _morphShapes
  }, [stencilItem])

  const deleteBtnStyle = useMemo(() => {
    if (bounds) {
      var shapeXY = bounds.upperLeft();
      var x = shapeXY.x;
      if (bounds.width() < 48) {
        x -= 24;
      }
      return {
        top: (shapeXY.y + bounds.height() + 2),
        left: x
      }
    } else {
      return {
        display: 'none'
      }
    }
  }, [bounds])

  const morphBtnStyle = useMemo(() => {
    if (bounds && morphShapes.length > 0) {
      var shapeXY = bounds.upperLeft();
      var x = shapeXY.x;
      if (bounds.width() < 48) {
        x -= 24;
      }
      return {
        top: (shapeXY.y + bounds.height() + 2),
        left: x + 24
      }
    } else {
      return {
        display: 'none'
      }
    }
  }, [bounds, morphShapes])

  const editBtnStyle = useMemo(() => {
    const showEditBtn = selectedShape?._stencil._jsonStencil.id.endsWith('CollapsedSubProcess')
    if (bounds && showEditBtn) {
      var shapeXY = bounds.upperLeft();
      var x = shapeXY.x;
      if (bounds.width() < 48) {
        x -= 24;
      }
      return {
        top: (shapeXY.y + bounds.height() + 2),
        left: x + (morphShapes.length > 0 ? 48 : 24)
      }
    } else {
      return {
        display: 'none'
      }
    }
  }, [bounds, morphShapes])

  const showQuickBtn = useMemo(() => {
    return stencilItem && (stencilItem.canConnect || stencilItem.canConnectAssociation)
  }, [stencilItem])

  const getQuickBtnStyle = useCallback((i) => {
    if (bounds) {
      var shapeXY = bounds.upperLeft();
      return {
        top: shapeXY.y + ((i - i % 3) / 3) * 24,
        left: shapeXY.x + bounds.width() + 5 + (i % 3) * 24,
      }
    } else {
      return {
        display: 'none'
      }
    }
  }, [bounds])

  const {
    showMorphChanger,
    toggleShowMorphChanger,
    handleChangeMorph
  } = useChangeMorph({
    selectedShape,
    editorManager
  })

  const triggerEditChildProcess = () => {
    const { resourceId } = selectedShape
    console.log(resourceId)
    editorManager.edit(resourceId);
  }

  return <>
    <MorphChanger
      visible={showMorphChanger}
      dataSource={morphShapes}
      onChange={handleChangeMorph}
      onCancel={toggleShowMorphChanger}
    ></MorphChanger>
    {
      showQuickBtn && quickMenuItems.map((el, i) => <div
        className="Oryx_button"
        key={i}
        style={getQuickBtnStyle(i)}
        onClick={() => {
          handleQuickAction({
            type: 'create',
            payload: el
          })
        }}
      >
        <QuickBtn stencil={el}>
          <img src={`${baseUrl}modeler/editor-app/stencilsets/bpmn2.0/icons/${el.icon}`} alt="" />
        </QuickBtn>
      </div>)
    }
    <div
      className="Oryx_button"
      style={deleteBtnStyle}
      onClick={() => {
        handleQuickAction({
          type: 'delete'
        })
      }}
    >
      <img src={`${baseUrl}modeler/editor-app/images/delete.png`} alt="" />
    </div>
    <div
      className="Oryx_button"
      style={morphBtnStyle}
      onClick={toggleShowMorphChanger}
    >
      <img src={`${baseUrl}modeler/editor-app/images/wrench.png`} alt="" />
    </div>
    <div
      className="Oryx_button"
      style={editBtnStyle}
      onClick={triggerEditChildProcess}
    >
      <img src={`${baseUrl}modeler/editor-app/images/pencil.png`} alt="" />
    </div>
  </>
}

export default QuickBtns